/********************************************************************/
/*          demo_main.c                                             */
/*            Download Program Main                                 */
/*                                                                  */
/*          Copyright (C) 1999-2001 NINTENDO Co.,Ltd.               */
/********************************************************************/
//#define CODE32
#include "sio32_multi_load.h"

//#define KEY_ON                              // Flag to enable OBJ key operation

#define INITIAL_CODE    (*(vu32 *)"AGBJ")   // Initial Code


/*-------------------- Global Variable  ----------------------------*/

    u16      HPos[MULTI_SIO_PLAYERS_MAX][2];    // OBJ Location Data
    u16      VPos[MULTI_SIO_PLAYERS_MAX][2];


/*==================================================================*/
/*                      Main Routine                                */
/*==================================================================*/
extern void intr_main(void);

void DemoMain(void)
{
    char  *StrTmp;
    s32    i, ii;

    RegisterRamReset(RESET_CPU_WRAM_FLAG                   // Initialization
                   | RESET_ALL_REG_FLAG ^ RESET_REG_SIO_FLAG);


    DmaCopy(3, IntrTable, IntrTableBuf,sizeof(IntrTableBuf),32);// Set Interrupt Table
    DmaCopy(3, intr_main, IntrMainBuf, sizeof(IntrMainBuf), 32);// Set Interrupt Main Routine
    *(vu32 *)INTR_VECTOR_BUF = (vu32 )IntrMainBuf;

    DmaArrayCopy(3, CharData_Sample, BG_VRAM+0x8000, 32);  //  Set BG Character
    DmaArrayCopy(3, CharData_Sample, OBJ_MODE0_VRAM, 32);  // Set OBJ Character
    DmaArrayCopy(3, PlttData_Sample, BG_PLTT,        32);  //  Set BG Palette
    DmaArrayCopy(3, PlttData_Sample, OBJ_PLTT,       32);  // Set OBJ Palette

    DmaArrayCopy(3, BgScData_Sample, BgBak,          32);  // Set BG Screen
    DmaArrayCopy(3, BgBak,           BG_VRAM,        32);

    DmaArrayClear(3,160,             OamBak,         32);  // Undisplayed OBJ moves outside screen
    DmaClear(     3,160,             OAM, OAM_SIZE,  32);
    DmaArrayCopy(3, OamData_Sample,  OamBak,         32);  // Set OAM
//    DmaArrayCopy(3, OamBak,          OAM,            32);

    for (i=0; i<MULTI_SIO_PLAYERS_MAX; i++)     OamBak[i].VPos = 200;

    *(vu16 *)REG_BG0CNT =                                  // Set BG Control
            BG_COLOR_16 | BG_SCREEN_SIZE_0 | BG_PRIORITY_0
            | 0 << BG_SCREEN_BASE_SHIFT | 2 << BG_CHAR_BASE_SHIFT ;

    *(vu16 *)REG_IE    = V_BLANK_INTR_FLAG;                // Enable V-Blank Interrupt
    if (*(vu8  *)(ROM_BANK0+0xb2) == 0x96                  // Check Game Pak Inserted
     && *(vu32 *)(ROM_BANK0+0xac) == INITIAL_CODE)
        *(vu16 *)REG_IE |= CASSETTE_INTR_FLAG;             // Enbale Game Pak Interrupt
    *(vu16 *)REG_STAT  = STAT_V_BLANK_IF_ENABLE;
    *(vu16 *)REG_IME   = 1;                                // Set IME

    *(vu16 *)REG_DISPCNT = DISP_MODE_0 | DISP_BG0_ON | DISP_OBJ_ON; // LCDC ON

    MultiSioInit(0);                                       // Muli-play Communication Initialization
    UsrSendBuf[0] = 200;
    UsrSendBuf[2] = 200;
    for (i=0; i<MULTI_SIO_PLAYERS_MAX; i++)
        for (ii=0; ii<2; ii++)
            VPos[i][ii] = 200;

    while(1) {
        VBlankIntrWait();                           // Wait for end V-Blank interrupt

		SioFlagsBak = SioFlags;
        SioFlags = MultiSioMain(UsrSendBuf, UsrRecvBuf, 0); // Multi-play Communication Main
        if (Trg)   MultiSioStart();                         // Multi-play Communication Start

        KeyRead();                                          // Key Operation

        if (SioFlags & MULTI_SIO_PARENT) {
            if (!SioStartFlag)    StrTmp = "PUSH ANY KEY  ";
            else                  StrTmp = "              ";
            BgScSet(StrTmp, &((u16 *)BG_VRAM)[32*18+7], 1);
        }

        if (!SioStartFlag) {                            // After confirm connect
            if (SioFlags & 0xf) {                       // initialize OBJ location
                UsrSendBuf[0] = ((OamData *)OamData_Sample)[((SioMultiCnt *)REG_SIOCNT)->ID].VPos;
                UsrSendBuf[1] = ((OamData *)OamData_Sample)[((SioMultiCnt *)REG_SIOCNT)->ID].HPos;
                UsrSendBuf[2] = ((OamData *)OamData_Sample)[((SioMultiCnt *)REG_SIOCNT)->ID].VPos;
                UsrSendBuf[3] = ((OamData *)OamData_Sample)[((SioMultiCnt *)REG_SIOCNT)->ID].HPos;
                SioStartFlag = 1;
            }
        } else {
            for (i=0; i<MULTI_SIO_PLAYERS_MAX; i++) {
                if (SioFlags & (1 << i)) {
                    VPos[i][0] = UsrRecvBuf[i][0];
                    HPos[i][0] = UsrRecvBuf[i][1];
                    VPos[i][1] = UsrRecvBuf[i][2];
                    HPos[i][1] = UsrRecvBuf[i][3];
				} else {
                    VPos[i][0] = VPos[i][1];
                    HPos[i][0] = HPos[i][1];
				}
                OamBak[i].VPos = VPos[i][0];
                OamBak[i].HPos = HPos[i][0];
            }

            // To enable SIO interrupt do not use DMA
            CpuFastArrayCopy(BgBak,  BG_VRAM);          // Set BG Screen
            CpuFastArrayCopy(OamBak, OAM    );          // Set OAM


            if ((SioFlags | SioFlagsBak) & 0xe
              && SioFlags & (1 << ((SioMultiCnt *)REG_SIOCNT)->ID)) {
                UsrSendBuf[0] = UsrSendBuf[2];
                UsrSendBuf[1] = UsrSendBuf[3];
#ifndef KEY_ON
                UsrSendBuf[3] -= 4;
#else
                if (Cont & U_KEY)    UsrSendBuf[2] -= 4;
                if (Cont & D_KEY)    UsrSendBuf[2] += 4;
                if (Cont & L_KEY)    UsrSendBuf[3] -= 4;
                if (Cont & R_KEY)    UsrSendBuf[3] += 4;
#endif
            }
        }
    }
}


